/**
 * 
 */
package org.vsg.stock.extension.service.impl;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

import javax.annotation.Resource;

import org.apache.commons.io.IOUtils;
import org.springframework.dao.DataAccessException;
import org.vsg.common.exceptions.service.ServiceException;
import org.vsg.stock.basic.domain.RealStockInfo;
import org.vsg.stock.basic.domain.StockCategory;
import org.vsg.stock.basic.domain.StockDailyLine;
import org.vsg.stock.basic.domain.StockInfo;
import org.vsg.stock.basic.domain.StockPerformance;
import org.vsg.stock.basic.persistence.StockCategoryDao;
import org.vsg.stock.basic.persistence.StockDailyLineDao;
import org.vsg.stock.basic.persistence.StockInfoDao;
import org.vsg.stock.basic.persistence.StockPerformanceDao;
import org.vsg.stock.extension.service.StockMigrationService;

/**
 * @author vison
 *
 */
public class StockMigrationServiceImpl implements StockMigrationService {
	
	@Resource
	private StockDailyLineDao stockDailyLineDao;
	
	@Resource
	private StockCategoryDao stockCategoryDao;

	@Resource
	private StockInfoDao stockInfoDao;	

	@Resource
	private StockPerformanceDao stockPerformanceDao;		
	
	private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");	
	
	public StockDailyLineDao getStockDailyLineDao() {
		return stockDailyLineDao;
	}


	public void setStockDailyLineDao(StockDailyLineDao stockDailyLineDao) {
		this.stockDailyLineDao = stockDailyLineDao;
	}

	public StockCategoryDao getStockCategoryDao() {
		return stockCategoryDao;
	}

	public void setStockCategoryDao(StockCategoryDao stockCategoryDao) {
		this.stockCategoryDao = stockCategoryDao;
	}

	public StockInfoDao getStockInfoDao() {
		return stockInfoDao;
	}

	public void setStockInfoDao(StockInfoDao stockInfoDao) {
		this.stockInfoDao = stockInfoDao;
	}


	/* (non-Javadoc)
	 * @see org.vsg.stock.custcomp.service.StockMigrationService#importDailyKLine(java.io.InputStream)
	 */
	@Override
	public void importDailyKLineFromFile(File dataMarketDir) throws ServiceException {
		// TODO Auto-generated method stub
		File[] stockFiles = dataMarketDir.listFiles();
		
		String stockCode = null;
		List<String> content  = null;
		InputStream is = null;
		
		DecimalFormat nf = new DecimalFormat("##0.00000");		
		
		for (int i = 0 ; i < stockFiles.length ; i++) {
			 // check is file
			if (stockFiles[i].isDirectory()) {
				continue;
			}
			
			stockCode = stockFiles[i].getName().substring(0,8);
			
			List<StockDailyLine> entiies = new Vector<StockDailyLine>();
			
			
			try {
				
				is = new BufferedInputStream( new FileInputStream(stockFiles[i]) );
				
				content = IOUtils.readLines( is );
				double lastClose = 0;
				for (int j = 0;  j < content.size() ; j++) {
					// --- at the last line ---
					String line = content.get(j);
					if ( line.equals("") ) {
						continue;
					}
					String[] lineData = line.split(",");
					String dateStr = lineData[1];
					double open = Double.parseDouble( lineData[2] ) ;
					double close = Double.parseDouble( lineData[5] );
					double high = Double.parseDouble( lineData[3] );
					double low = Double.parseDouble( lineData[4] );
					double vol = Double.parseDouble( lineData[6] );
					double trasValue = Double.parseDouble( lineData[7] );
					double yieldRate =  Double.parseDouble( lineData[8] );
					
					StockDailyLine entity = new StockDailyLine();
					entity.setStockCode( stockCode );
					try {
						entity.setDate( sdf.parse( dateStr ) );
					} catch (ParseException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					entity.setOpen(open);
					entity.setHigh(high);
					entity.setLow(low);
					entity.setClose(close);
					entity.setVol((long)vol);
					entity.setTransactionValue(trasValue);
					entity.setYieldRate( yieldRate );
					if ( j+1 != content.size()) {
						String nextline = content.get(j+1);
						String[] nextlineData = nextline.split(",");
						lastClose = Double.parseDouble( nextlineData[5] );
						
						double realRate = Double.parseDouble( nf.format( (close - lastClose) / lastClose )  );
						if (realRate != yieldRate) {
							entity.setExRights( (short)1 );
						}
					}
					
					entiies.add( entity );
					
					stockDailyLineDao.saveAll( entiies );
				}				
				
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				if (is != null) {
					try {
						is.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} finally {
						
					}
				}
			}

			
		}

     
	}

	
	@Override
	public void importDailyKLineFromFile(File dataMarketDir, Date specifiedDate)
			throws ServiceException {
		// TODO Auto-generated method stub
		File[] stockFiles = dataMarketDir.listFiles();
		
		String stockCode = null;
		String content  = null;
		InputStream is = null;
		
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		
		List<StockDailyLine> entiies = new Vector<StockDailyLine>();
		
		DecimalFormat nf = new DecimalFormat("##0.00000");		
		
		for (int i = 0 ; i < stockFiles.length ; i++) {
			 // check is file
			if (stockFiles[i].isDirectory()) {
				continue;
			}
			
			stockCode = stockFiles[i].getName().substring(0,8);
			

			
			try {
				
				is = new BufferedInputStream( new FileInputStream(stockFiles[i]) );

				content = IOUtils.toString( is );
				
				// --- check the data exist in the content ---
				int dataPositionIndex = content.indexOf(sdf.format(specifiedDate));
				if (dataPositionIndex == -1) {
					continue;
				}

				String beforeContent = content.substring(0, dataPositionIndex);
				int beforeEnding = beforeContent.lastIndexOf("\n");
				if (beforeEnding != -1) {
					String afterContent = content.substring(beforeEnding+1);
					int afterEnding = afterContent.indexOf("\n");
					String lineContent = content.substring(beforeEnding+1 , beforeEnding +afterEnding);
					String[] lineData = lineContent.split(",");
					String dateStr = lineData[1];
					double open = Double.parseDouble( lineData[2] ) ;
					double close = Double.parseDouble( lineData[5] );
					double high = Double.parseDouble( lineData[3] );
					double low = Double.parseDouble( lineData[4] );
					double vol = Double.parseDouble( lineData[6] );
					double trasValue = Double.parseDouble( lineData[7] );
					double yieldRate =  Double.parseDouble( lineData[8] );				

					StockDailyLine entity = new StockDailyLine();
					entity.setStockCode( stockCode );
					try {
						entity.setDate( sdf.parse( dateStr ) );
					} catch (ParseException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					entity.setOpen(open);
					entity.setHigh(high);
					entity.setLow(low);
					entity.setClose(close);
					entity.setVol((long)vol);
					entity.setTransactionValue(trasValue);
					entity.setYieldRate( yieldRate );
				
					entiies.add( entity );
					
				}
				
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				if (is != null) {
					try {
						is.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} finally {
						
					}
				}
			}
		}
		
		// --- add to db
		stockDailyLineDao.saveAll( entiies );		
		
	}


	@Override
	public void importDailyKLineFromFile(File dataMarketDir, String stockCode,
			Date specifiedDate) throws ServiceException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void updateStockCategoryFromVsatData(File dataDir)
			throws ServiceException {
		// TODO Auto-generated method stub
		File[] subDir = dataDir.listFiles();
		
		File dir = null;

		Collection<String> allDescription = this.stockCategoryDao.findAllDescription();		
		
		Collection<StockCategory> allStockCategories = new Vector<StockCategory>();
		
		for (int i = 0 ; i < subDir.length ; i++) {
			dir = subDir[i];
			File[] infoDataFiles = dir.listFiles();
			InputStream is = null;
			for (int j = 0 ; j < infoDataFiles.length ; j++) {
				
				try {
					is = new BufferedInputStream( new FileInputStream(infoDataFiles[j]) );
					
					String content = IOUtils.toString( is , "GBK");

					String concept = "【同大股东个股】";
					String otherConcept = "【同行业个股】";
					int position = content.indexOf(concept);
					int otherPosition = content.indexOf(otherConcept);
					if (position > 0 && otherPosition >0 && otherPosition > position) {
						String nextContent = content.substring(position+concept.length()+2 ,otherPosition);
						ByteArrayInputStream bais = new ByteArrayInputStream(nextContent.getBytes());
						List<String> lines = IOUtils.readLines( bais );
						for (int k = 0 ; k < lines.size() ; k++) {
							if (lines.get(k).startsWith("┌─────────────────────────────┐")) {
								// --- get the last line ---
								String contentCode = lines.get(k-1);
								if (contentCode.indexOf("截止日期") != -1 || contentCode.indexOf("截至日期") != -1) {
									continue;
								}						
								if (!allDescription.contains( contentCode.trim() ) ) {
									
									StockCategory sc = new StockCategory();
									sc.setType( StockCategory.SAME_STOCKHOLDER );
									sc.setDescription( contentCode.trim() );
									allStockCategories.add( sc );
									
									allDescription.add( contentCode.trim() );
								}

							}
						}
						bais.close();
						
					}
					
					concept = "【同概念个股】";
					position = content.indexOf(concept);
					if (position > 0) {
						String nextContent = content.substring(position+concept.length()+2);
						
						int symbolBeginPosi = 0;
						ByteArrayInputStream bais = new ByteArrayInputStream(nextContent.getBytes());
						List<String> lines = IOUtils.readLines( bais );
						for (int k = 0 ; k < lines.size() ; k++) {
							if (lines.get(k).startsWith("┌─────────────────────────────┐")) {
								// --- get the last line ---
								String contentCode = lines.get(k-1);
								if (contentCode.equals("")) {
									continue;
								}
							
								String conceptContent = contentCode.substring( 1, contentCode.length()-1);
								conceptContent = conceptContent.replaceFirst("板块", "");
								if (conceptContent.indexOf("截止日期") != -1 || conceptContent.indexOf("截至日期") != -1) {
									continue;
								}							

								if (!allDescription.contains( conceptContent.trim() ) ) {
									StockCategory sc = new StockCategory();
									sc.setType( StockCategory.CONCEPT );
									sc.setDescription( conceptContent.trim() );
									allStockCategories.add( sc );
									
									allDescription.add( conceptContent.trim() );
								}

							}
						}
						bais.close();
						
					}

					
				} catch (FileNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException ioe) {
					ioe.printStackTrace();
				} finally {
					if (is != null) {
						try {
							is.close();
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}finally {
							is = null;
						}
					}
				}
				
			}
		}
		
		stockCategoryDao.saveAll( allStockCategories );
		
	}

	@Override
	public void updateDZHBlockToStockCategoryFromFile(File dataDir)
			throws ServiceException {
		// TODO Auto-generated method stub
		File blockFile = new File(dataDir,"BLOCK.DEF");
		
		
		Collection<String> allDescription = this.stockCategoryDao.findAllDescription();
		Collection<StockCategory> allStockCategories = new Vector<StockCategory>();		
		String categoryName = null;
		InputStream is = null;
		try {
			is = new BufferedInputStream(new FileInputStream(blockFile));

			List<String> content = IOUtils.readLines(is, "GBK");
			String data = null;
			int state = 0;
			for (Iterator<String> contentIter = content.iterator(); contentIter
					.hasNext();) {
				data = contentIter.next();
				if (data.equals("[行业]")) {
					state = 1;
					continue;
				} else if (data.equals("[概念]")) {
					state = 2;
					continue;
				} else if (data.equals("[地域]")) {
					state = 3;
					continue;
				} else if (data.equals("[证监会行业]")) {
					state = 4;
					continue;
				} else if (data.equals("[指数板块]")) {
					state = 5;
					continue;
				} else if (data.equals("[其它板块]")) {
					state = 6;
					continue;
				}
				// --- update the content ---
				if (state != 0) {
					if (data.indexOf("HK") != -1 || data.indexOf("自选股") != -1
							|| data.indexOf("深证Ｂ指") != -1
							|| data.indexOf("恒生") != -1
							|| data.indexOf("A股板块") != -1
							|| data.indexOf("A股指数") != -1
							|| data.indexOf("B股板块") != -1
							|| data.indexOf("巨潮1000") != -1
							|| data.indexOf("选股池1") != -1
							|| data.indexOf("筹") != -1
							|| data.indexOf("恒指成份") != -1
							|| data.indexOf("港") != -1
							|| data.indexOf("关注股票") != -1
							|| data.indexOf("权证板块") != -1
							|| data.indexOf("B股指数") != -1
							|| data.indexOf("成份Ｂ指") != -1
							|| data.indexOf("每经G股") != -1) {
						continue;
					}
				}
				String desc = null;
				boolean exist = false;
				for (Iterator<String> descIter = allDescription.iterator(); descIter
						.hasNext();) {
					desc = descIter.next();
					if (desc.equals(data)) {
						exist = true;
						break;
					}
				}
				if (!exist && !allDescription.contains(data.trim())) {
					StockCategory sc = new StockCategory();
					if (state == 1) {
						sc.setType(StockCategory.TRADES);
					} else if (state == 2) {
						sc.setType(StockCategory.CONCEPT);
					} else if (state == 3) {
						sc.setType(StockCategory.ZONE);
					} else if (state == 4) {
						sc.setType(StockCategory.STANDARD_TRADES);
					} else if (state == 5) {
						sc.setType(StockCategory.PLATE);
					} else if (state == 6) {
						sc.setType(StockCategory.OTHERS);
					}
					sc.setDescription(data.trim());
					allStockCategories.add(sc);
					allDescription.add( data.trim() );
				}

			}

		} catch (IOException ioe) {
			ioe.printStackTrace();
		} finally {
			if (is != null) {
				try {
					is.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} finally {
					is = null;
				}
			}
		}

		stockCategoryDao.saveAll(allStockCategories);		
		
	}

	@Override
	public void updateStockInfo(File stockDataDir) throws ServiceException {
		// TODO Auto-generated method stub
		File[] subFiles = stockDataDir.listFiles();		
		
		Collection<String> allStockName = this.stockInfoDao.findAllName();
		
		Collection<StockInfo> entities = new Vector<StockInfo>();
		
		File file = null;
		InputStream is = null;
		for( int i = 0  ; i < subFiles.length ; i++) {
			file = subFiles[i];
			if (file.isDirectory()) {
				continue;
			}
			
			try {
				is = new BufferedInputStream( new FileInputStream( file) );
				
				List<String> contentList  = IOUtils.readLines(is, "GBK");
				
				String market = file.getName().substring(0,2);
				String line = null;
				for (int j = 2; j < contentList.size() ; j++) {
					line = contentList.get(j);
					if (market.equals("SH")) {
						if (line.startsWith("60")) {
							String[] spri = line.split("	");
							if (!allStockName.contains(spri[1])) {
								StockInfo si = new StockInfo();
								si.setCode( "SH"+spri[0] );
								si.setName( spri[1] );
								entities.add(si);
							}
						}
					} else if (market.equals("SZ")) {
						if (line.startsWith("00") || line.startsWith("30")) {
							String[] spri = line.split("	");
							if (!allStockName.contains(spri[1])) {
								StockInfo si = new StockInfo();
								si.setCode( "SZ"+spri[0] );
								si.setName( spri[1] );
								entities.add(si);
							}							
						}
					}
					
				}
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				if (is != null) {
					try {
						is.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
			
		}
		
		this.stockInfoDao.saveAll( entities );
		
	}


	
	@Override
	public void updateStockAndCategoryMapFromDZHFile(File block)
			throws ServiceException {
		// TODO Auto-generated method stub
		FilenameFilter ff = new FilenameFilter() {

			@Override
			public boolean accept(File arg0, String fileName) {
				// TODO Auto-generated method stub
				if (fileName.indexOf("BLOCK") != -1) {
					return false;
				}
				if (fileName.indexOf("HK") != -1 || fileName.indexOf("自选股") != -1
						|| fileName.indexOf("深证Ｂ指") != -1
						|| fileName.indexOf("恒生") != -1
						|| fileName.indexOf("A股板块") != -1
						|| fileName.indexOf("A股指数") != -1
						|| fileName.indexOf("B股板块") != -1
						|| fileName.indexOf("巨潮1000") != -1
						|| fileName.indexOf("选股池1") != -1
						|| fileName.indexOf("筹") != -1
						|| fileName.indexOf("恒指成份") != -1
						|| fileName.indexOf("港") != -1
						|| fileName.indexOf("关注股票") != -1
						|| fileName.indexOf("权证板块") != -1
						|| fileName.indexOf("B股指数") != -1
						|| fileName.indexOf("成份Ｂ指") != -1
						|| fileName.indexOf("P ") != -1
						|| fileName.indexOf("每经G股") != -1) {
					return false;
				}				
				return true;
			}
			
		};
		
		File[] subFiles = block.listFiles(ff);
		
		InputStream is = null;
		
		Map<String,List<String>> categoryStockMap = new HashMap<String,List<String>>();
		
		List<String> allStkCodes = this.stockInfoDao.findAllCode();
		
		for (int i = 0 ; i < subFiles.length ; i++) {
			if (subFiles[i].isDirectory()) {
				continue;
			}
			
			String category = subFiles[i].getName().substring(0 , subFiles[i].getName().indexOf("."));
			
			List<String> cateStocks = new Vector<String>();
			
			try {
				is = new BufferedInputStream(new FileInputStream(subFiles[i]));
				
				String contentStock = IOUtils.toString( is , "GBK");

				do {
					int szPosition = contentStock.indexOf("SZ");
					int hPosition = contentStock.indexOf("H");
					
					String stkCode = null;
					if (szPosition != -1) {
						stkCode = contentStock.substring( szPosition+2 , szPosition+8 );
						contentStock = contentStock.substring( szPosition+8 );
						if (!(stkCode.startsWith("00") || stkCode.startsWith("30")) ) {
							continue;
						}						
						stkCode="SZ"+stkCode;
						
						
					}
					else if (hPosition != -1) {
						stkCode = contentStock.substring( hPosition+1 , hPosition+7 );
						contentStock = contentStock.substring( hPosition+7 );
						if (!stkCode.startsWith("60")) {
							continue;
						}
						stkCode="SH"+stkCode;
					}

					
					if (!allStkCodes.contains( stkCode )) {
						continue;
					}
					cateStocks.add(stkCode);
				} while (contentStock.indexOf("SZ") != -1 || contentStock.indexOf("SH") != -1); 
				
				categoryStockMap.put(category , cateStocks);
				
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
			finally {
				if (is == null) {
					try {
						is.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					
				}
			}
		}
		
		// --- update teh map entry ---
		try {
			
			this.stockCategoryDao.updateBatchToStockInfoMapping(categoryStockMap);
		} catch (DataAccessException dae) {
			dae.printStackTrace();
		}

		

		
	}


	@Override
	public void updateStockAndCategoryMapFromVsatData(File dataDir)
			throws ServiceException {
		// TODO Auto-generated method stub
		File[] subDir = dataDir.listFiles();
		
		File dir = null;
		
		Set<String> existCateGroup = new HashSet<String>();
		Map<String,List<String>> categoryStockMap = new HashMap<String,List<String>>();
		List<String> allStkCodes = this.stockInfoDao.findAllCode();
		// --- check defined sql exist ---
		
		

		for (int i = 0 ; i < subDir.length ; i++) {
			dir = subDir[i];
			File[] infoDataFiles = dir.listFiles();
			InputStream is = null;
			for (int j = 0 ; j < infoDataFiles.length ; j++) {
				if (infoDataFiles[j].isDirectory()) {
					continue;
				}
				String code = infoDataFiles[j].getName().substring(0,6);
				if (code.startsWith("60")) {
					code="SH"+code;
				} else if (code.startsWith("00") || code.startsWith("30") ) {
					code="SZ"+code;
				}
				
				if (!allStkCodes.contains(code)) {
					continue;
				}

				// --- check description defined ---
			
				
				try {
					is = new BufferedInputStream( new FileInputStream(infoDataFiles[j]) );
					
					String content = IOUtils.toString( is , "GBK");

					String concept = "【同大股东个股】";
					String otherConcept = "【同行业个股】";
					int position = content.indexOf(concept);
					int otherPosition = content.indexOf(otherConcept);
					if (position > 0 && otherPosition >0 && otherPosition > position) {
						String nextContent = content.substring(position+concept.length()+2 ,otherPosition);
						ByteArrayInputStream bais = new ByteArrayInputStream(nextContent.getBytes());
						List<String> lines = IOUtils.readLines( bais );
						for (int k = 0 ; k < lines.size() ; k++) {
							if (lines.get(k).startsWith("┌─────────────────────────────┐")) {
								// --- get the last line ---
								String cateDescContent = lines.get(k-1);
								if (cateDescContent.indexOf("截止日期") != -1 || cateDescContent.indexOf("截至日期") != -1) {
									continue;
								}
								// --- check cateGroup exist ---
								if (!existCateGroup.contains( cateDescContent.trim() )) {
									existCateGroup.add( cateDescContent.trim() );
									categoryStockMap.put(cateDescContent.trim(), new Vector<String>());
								}
								List<String> assoStks = categoryStockMap.get( cateDescContent.trim() );
								if (!assoStks.contains( code ) ) {
									assoStks.add( code );
									categoryStockMap.put(cateDescContent.trim(), assoStks);
								}

							}
						}
						bais.close();
						
					}
					
					concept = "【同概念个股】";
					position = content.indexOf(concept);
					if (position > 0) {
						String nextContent = content.substring(position+concept.length()+2);
						
						int symbolBeginPosi = 0;
						ByteArrayInputStream bais = new ByteArrayInputStream(nextContent.getBytes());
						List<String> lines = IOUtils.readLines( bais );
						for (int k = 0 ; k < lines.size() ; k++) {
							if (lines.get(k).startsWith("┌─────────────────────────────┐")) {
								// --- get the last line ---
								String cateDescContent = lines.get(k-1);
								if (cateDescContent.equals("")) {
									continue;
								}
							
								cateDescContent = cateDescContent.substring( 1, cateDescContent.length()-1);
								cateDescContent = cateDescContent.replaceFirst("板块", "");
								if (cateDescContent.indexOf("截止日期") != -1 || cateDescContent.indexOf("截至日期") != -1) {
									continue;
								}							
								// --- check cateGroup exist ---
								if (!existCateGroup.contains( cateDescContent.trim() )) {
									existCateGroup.add( cateDescContent.trim() );
									categoryStockMap.put(cateDescContent.trim(), new Vector<String>());
								}
								List<String> assoStks = categoryStockMap.get( cateDescContent.trim() );
								if (!assoStks.contains( code ) ) {
									assoStks.add( code );
									categoryStockMap.put(cateDescContent.trim(), assoStks);
								}

							}
						}
						bais.close();
						
					}

					
				} catch (FileNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException ioe) {
					ioe.printStackTrace();
				} finally {
					if (is != null) {
						try {
							is.close();
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}finally {
							is = null;
						}
					}
				}
				
			}
		}
		
		try {
			this.stockCategoryDao.updateBatchToStockInfoMapping(categoryStockMap);
		} catch (DataAccessException dae) {
			dae.printStackTrace();
		}

		
		
	}


	@Override
	public void updateDailyLine(File file) throws ServiceException {
		// TODO Auto-generated method stub
		InputStream is = null;
		try {
			is = new BufferedInputStream( new FileInputStream( file) );
	
			List<String> lines = IOUtils.readLines(is);
			
			List<StockDailyLine> todaySdls = new ArrayList<StockDailyLine>();
			
			String line = null;
			StockDailyLine sdl = null;
			for (Iterator<String> linesIter = lines.iterator() ; linesIter.hasNext(); ) {
				try {
					line = linesIter.next();
					String[] data = line.split(",");
					sdl = new StockDailyLine();
					sdl.setStockCode(data[0]);
					sdl.setDate( sdf.parse(data[1]) );
					sdl.setOpen(new Double(data[2]) );
					sdl.setHigh( new Double(data[3]) );
					sdl.setLow( new Double(data[4]) );
					sdl.setClose( new Double(data[5]) );
					sdl.setVol( (long) Double.parseDouble( data[6] ) );
					sdl.setTransactionValue( new Double(data[7] ));
					sdl.setYieldRate(new Double(data[8]) );
					sdl.setExRights(new Short(data[9]) );
					
					todaySdls.add(sdl);
					
				} catch (ParseException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			}
			
			stockDailyLineDao.saveAll(todaySdls);

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		
		} finally {
			
			if (is != null) {
				
				try {
					is.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			}
			
		}			


	}


	@Override
	public StockInfo updateStockInfoFromVsatData(StockInfo info, File stockVsatFile)
			throws ServiceException {
		// TODO Auto-generated method stub
		
		if (! (info instanceof RealStockInfo) ) {
			return info;
		}
		
		RealStockInfo realStockInfo = (RealStockInfo)info;
		
		InputStream is = null;
		try {
			is = new BufferedInputStream( new FileInputStream(stockVsatFile) );
			
			String content = IOUtils.toString( is , "GBK");

			String totaLscapTitle = "万):";
			String nextStr = "│法";
			String nextStr2="│董";
			
			int firstPos = content.indexOf(totaLscapTitle);
			int nextPos = content.indexOf(nextStr);
			int nextPos2 = content.indexOf(nextStr2);
			if ( nextPos != -1 || nextPos2 != -1) {
				if (nextPos2 != -1) {
					nextPos = nextPos < nextPos2 ? nextPos : nextPos2;
				}
			}
			
			Double capital = null;
			if (firstPos > 0 && nextPos >0 && nextPos > firstPos) {
				String capStr = content.substring(firstPos+totaLscapTitle.length() ,nextPos);
				if (!capStr.trim().equals("")) {
					capital =  new Double(capStr.trim());
				}
			}
			content = content.substring(nextPos);
			
			totaLscapTitle = "万):";
			nextStr = "│总";
			nextStr2="│行";
			String nextStr3="│Guernier";
			firstPos = content.indexOf(totaLscapTitle);
			if (firstPos == -1) {
				firstPos = content.indexOf("(万)");
				
			}
			nextPos = content.indexOf(nextStr);
			nextPos2 = content.indexOf(nextStr2);
			int nextPos3 = content.indexOf(nextStr3);
			if ( nextPos != -1 || nextPos2 != -1 || nextPos3 != -1) {
				if (nextPos2 != -1) {
					nextPos = nextPos < nextPos2 ? nextPos : nextPos2;
				} else if (nextPos3 != -1) {
					nextPos = nextPos < nextPos3 ? nextPos : nextPos3;
				}
			}
			Double aCapital = null;
			if (firstPos > 0 && nextPos >0 && nextPos > firstPos) {
				String capStr = content.substring(firstPos+totaLscapTitle.length() ,nextPos);
				if (!capStr.trim().equals("")) {
					aCapital =  new Double(capStr.trim());
				}
			}
			

			realStockInfo.setCapital(capital);
			realStockInfo.setACapital(aCapital);

		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException ioe) {
			ioe.printStackTrace();
		} finally {
			if (is != null) {
				try {
					is.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}finally {
					is = null;
				}
			}
		}
		return realStockInfo;
	}


	@Override
	public void updateStockPerformanceFromVsatData(File vastDir)
			throws ServiceException {
		// TODO Auto-generated method stub
		
		SimpleDateFormat df = new SimpleDateFormat("yy-MM-dd");		
		
		File[] subDir = vastDir.listFiles();
		
		List<StockPerformance> updateSPList = new ArrayList<StockPerformance>();
		
		File dir = null;
		for (int i = 0 ; i < subDir.length ; i++) {
			File[] infoDataFiles = subDir[i].listFiles();
			InputStream is = null;
			for (int j = 0 ; j < infoDataFiles.length ; j++) {
				if (infoDataFiles[j].isDirectory()) {
					continue;
				}
				// --- check the remove handle ---
				String code = infoDataFiles[j].getName().substring(0,6);
				if (code.startsWith("60")) {
					code="SH"+code;
				} else if (code.startsWith("00") || code.startsWith("30") ) {
					code="SZ"+code;
				}
				
				List<Date> dateArrayList = null;
				List<Double> aIncomeList = null;
				List<Double> netAssetList = null;
				List<Double> aReserveFundList = null;
				List<Double> undistributedProfitList = null;
				
				try {
					is = new BufferedInputStream( new FileInputStream(infoDataFiles[j]) );
					
					String content = IOUtils.toString( is , "GBK");
					
					String firstKey = "按最新总股本计算";
					String secondKey = "────────┴────┴─┬──┴────┴──";
					String thirdKey =  "────────┴────┴─┬──┴────┴──";
					int firstlocationIndex = content.indexOf( firstKey );
					int secondlocationIndex = content.indexOf( secondKey );

					String orgContent = content.substring(firstlocationIndex, secondlocationIndex);
					ByteArrayInputStream baIs = new ByteArrayInputStream(orgContent.getBytes());
					
					List<String> lines = IOUtils.readLines(baIs);
					String line = null;
					for (Iterator<String> linesIter = lines.iterator() ; linesIter.hasNext(); ) {
						line = linesIter.next();
						String[] lineData = line.split("│");
						
						// --- get the date handle --
						if (lineData[0].trim().equals("按最新总股本计算")) {
							dateArrayList = new Vector<Date>();
							for (int a = 1; a < lineData.length;a++) {
								try {
									dateArrayList.add( df.parse(lineData[a].trim()) );
								} catch (ParseException e) {
									// TODO Auto-generated catch block
									e.printStackTrace();
								}
							}
						}

						else if (lineData[0].trim().equals("每股收益")) {
							aIncomeList = new LinkedList<Double>();
							for (int a = 1; a < lineData.length;a++) {
								try {
									aIncomeList.add( Double.parseDouble( lineData[a].trim() ) );
								} catch (NumberFormatException e) {
									// TODO Auto-generated catch block
									aIncomeList.add(null);
								}
							}
						}
						
						else if (lineData[0].trim().equals("每股净资产")) {
							netAssetList = new LinkedList<Double>();
							for (int a = 1; a < lineData.length;a++) {
								try {
									netAssetList.add( Double.parseDouble( lineData[a].trim() ) );
								} catch (NumberFormatException e) {
									// TODO Auto-generated catch block
									netAssetList.add(null);
								}
							}
						}							

						else if (lineData[0].trim().equals("每股资本公积金")) {
							aReserveFundList = new LinkedList<Double>();
							for (int a = 1; a < lineData.length;a++) {
								try {
									aReserveFundList.add( Double.parseDouble( lineData[a].trim() ) );
								} catch (NumberFormatException e) {
									// TODO Auto-generated catch block
									aReserveFundList.add(null);
								}
							}
						}
						
						else if (lineData[0].trim().equals("每股未分配利润")) {
							undistributedProfitList = new LinkedList<Double>();
							for (int a = 1; a < lineData.length;a++) {
								try {
									undistributedProfitList.add( Double.parseDouble( lineData[a].trim() ) );
								} catch (NumberFormatException e) {
									// TODO Auto-generated catch block
									undistributedProfitList.add(null);
								}
							}
						}
						
					}
					
					// --- read all the code ---
					Date tempDate = null;
			
					for (int b = 0 ; b < dateArrayList.size() ; b++) {
						tempDate = dateArrayList.get(b);
						if (tempDate != null) {
							//StockPerformance sp = stockPerformanceDao.getStockPerformanceByCode(code, tempDate);
								StockPerformance sp = new StockPerformance();

								sp.setStockCode( code ) ;
								sp.setPublishDate( tempDate );
								sp.setaIncome( aIncomeList.get(b) );
								sp.setNetAsset( netAssetList.get( b ) );
								sp.setaReserveFund( aReserveFundList.get( b ) );
								sp.setUndistributedProfit( undistributedProfitList.get( b ) );
								
								updateSPList.add( sp );

						}
					}
					
				} catch (FileNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException ioe) {
					ioe.printStackTrace();
				} finally {
					if (is != null) {
						try {
							is.close();
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}finally {
							is = null;
						}
					}
				}				
				
			}
		}
		

		// --- handle list ---
		stockPerformanceDao.addAll(updateSPList );		

	}



	
	
}
